package com.wshl.cloudservice.ui.widget;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class MySurfaceView3 extends SurfaceView implements SurfaceHolder.Callback, View.OnTouchListener {


    private static final int NONE = 0;// 原始
    private static final int DRAG = 1;// 拖动
    private static final int ZOOM = 2;// 放大
    private int mStatus = NONE;

    private static final float MAX_ZOOM_SCALE = 5f;
    private static final float MIN_ZOOM_SCALE = 1.0f;
    private static final float FLOAT_TYPE = 1.0f;
    private float mCurrentMaxScale = MAX_ZOOM_SCALE;
    private float mCurrentScale = 1.0f;

    private Rect mRectSrc = new Rect(); // used for render image.  //要绘图的位置
    private Rect mRectDes = new Rect(); // used for store size of monitor. 要画图的部分

    private int mCenterX, mCenterY;
    int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;

    private PointF mStartPoint = new PointF();
    private float mStartDistance = 0f;

    private SurfaceHolder mSurHolder = null;
    private Bitmap mBitmap;

    /********************画图部分********************/
    private Paint shapePaint;
    private String paintColor = "FA1418";//当前画笔颜色
    private int paintWidth = 3;//画笔宽度

    private float startX = 0, startY = 0, endX = 0, endY = 0;//位置比例
    private float sx = 0, sy = 0, ex = 0, ey = 0; //计算出来当前屏幕中真实位置
    private boolean isDrawShape = false;//当前是否处于画图状态




    /**
     * 计算点X到图片左上角距离与图片宽度的比值
     *
     * @param bmW    图片宽
     * @param pointX 点相对于屏幕左上角的X距离
     * @return
     */
    private float pointScreen2ImageX(int bmW, float pointX) {
        return (pointX / mWidthScale - mRectDes.left + mRectSrc.left) * 1.0f / (bmW);
    }

    /**
     * 计算点Y到图片左上角与图片高度的比值
     *
     * @param bmH    图片高度
     * @param pointY 点相对于屏幕左上角的Y距离
     * @return
     */
    private float pointScreen2ImageY(int bmH, float pointY) {
        return (pointY / mHeightScale - mRectDes.top + mRectSrc.top) * 1.0f / (bmH);
    }

    /**
     * 把相对于图片的宽比值转换成相对于屏幕上具体的点
     *
     * @param bmW    图片宽度
     * @param scaleX 点的X值相对于图片宽度的比值
     * @return
     */
    private float pointImage2ScreenX(int bmW, float scaleX) {
        return (scaleX * bmW + mRectDes.left - mRectSrc.left) * mWidthScale;
    }

    /**
     * 把相对于图片的高度壁纸转换成相对于屏幕上具体的点
     *
     * @param bmH    图片高度
     * @param scaleY 点的Y值相对于图片高度的比值
     * @return
     */
    private float pointImage2ScreenY(int bmH, float scaleY) {
        return (scaleY * bmH + mRectDes.top - mRectSrc.top) * mHeightScale;
    }

    /********************画图部分********************/

    public MySurfaceView3(Context context, AttributeSet attrs) {
        super(context, attrs);
        mSurHolder = getHolder();
        mSurHolder.addCallback(this);
        this.setOnTouchListener(this);
    }

    private void init() {
        mCurrentMaxScale = Math.max(MIN_ZOOM_SCALE,
                4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f * mImageWidth / mSurfaceWidth));
        mCurrentScale = MIN_ZOOM_SCALE;
        mCenterX = mImageWidth / 2;
        mCenterY = mImageHeight / 2;

        calcRect();
    }

    private void adjustCenter() {
        int w = mRectSrc.right - mRectSrc.left;
        int h = mRectSrc.bottom - mRectSrc.top;

        if (mCenterX - w / 2 < 0) {
            mCenterX = w / 2;
            mRectSrc.left = 0;
            mRectSrc.right = w;
        } else if (mCenterX + w / 2 >= mImageWidth) {
            mCenterX = mImageWidth - w / 2;
            mRectSrc.right = mImageWidth;
            mRectSrc.left = mRectSrc.right - w;
        } else {
            mRectSrc.left = mCenterX - w / 2;
            mRectSrc.right = mRectSrc.left + w;
        }

        if (mCenterY - h / 2 < 0) {
            mCenterY = h / 2;
            mRectSrc.top = 0;
            mRectSrc.bottom = h;
        } else if (mCenterY + h / 2 >= mImageHeight) {
            mCenterY = mImageHeight - h / 2;
            mRectSrc.bottom = mImageHeight;
            mRectSrc.top = mRectSrc.bottom - h;
        } else {
            mRectSrc.top = mCenterY - h / 2;
            mRectSrc.bottom = mRectSrc.top + h;
        }
    }

    private float mWidthScale = 1.0f;//当前宽的缩放比例
    private float mHeightScale = 1.0f;//当前高的缩放比例
    float distanceX;
    float distancY;

    private void calcRect() {
        int w, h;
        float imageRatio, surfaceRatio;
        imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight;
        surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight;

        if (imageRatio < surfaceRatio) {
            h = mSurfaceHeight;
            w = (int) (h * imageRatio);
        } else {
            w = mSurfaceWidth;
            h = (int) (w / imageRatio);
        }

        if (mCurrentScale > MIN_ZOOM_SCALE) {   //如果显示区域超过屏幕宽高，则取屏幕宽高
            w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale));
            h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale));
        } else {
            mCurrentScale = MIN_ZOOM_SCALE;
        }

        String msg = "imageRatio：" + imageRatio + "   surfaceRatio：" + surfaceRatio + "   mCurrentScale:" + mCurrentScale
                + "     w：" + w + "     h：" + h
                + "      mSurfaceWidth：" + mSurfaceWidth + "     mSurfaceHeight：" + mSurfaceHeight
                + "      mImageWidth：" + mImageWidth + "     mImageHeight：" + mImageHeight;
        Log.i("TAG  radio", msg);

        mRectDes.left = (mSurfaceWidth - w) / 2;
        mRectDes.top = (mSurfaceHeight - h) / 2;
        mRectDes.right = mRectDes.left + w;
        mRectDes.bottom = mRectDes.top + h;

        float curImageRatio = FLOAT_TYPE * w / h;
        int h2, w2;
        if (curImageRatio > imageRatio) {
            h2 = (int) (mImageHeight / mCurrentScale);
            w2 = (int) (h2 * curImageRatio);
        } else {
            w2 = (int) (mImageWidth / mCurrentScale);
            h2 = (int) (w2 / curImageRatio);
        }

        mRectSrc.left = mCenterX - w2 / 2;
        mRectSrc.top = mCenterY - h2 / 2;
        mRectSrc.right = mRectSrc.left + w2;
        mRectSrc.bottom = mRectSrc.top + h2;

        distanceX = (mSurfaceWidth - w) / 2 - (mCenterX - w2 / 2);
        distancY = (mSurfaceHeight - h) / 2 - (mCenterY - h2 / 2);

        mWidthScale = w * FLOAT_TYPE / w2;//计算当前宽度缩放比例
        mHeightScale = h * FLOAT_TYPE / h2;//计算当前高度缩放比例
    }

    public void setMaxZoom(float value) {
        mCurrentMaxScale = value;
    }

    public void setBitmap(Bitmap b) {
        if (b == null) {
            return;
        }
        synchronized (MySurfaceView3.class) {
            mBitmap = b;
            if (mImageHeight != mBitmap.getHeight() || mImageWidth != mBitmap.getWidth()) {
                mImageHeight = mBitmap.getHeight();
                mImageWidth = mBitmap.getWidth();
                init();
            }
            showBitmap();
        }
    }

    private void showBitmap() {
        synchronized (MySurfaceView3.class) {
            Canvas c = getHolder().lockCanvas();
            if (c != null && mBitmap != null) {
                c.drawColor(Color.GRAY);
                c.drawBitmap(mBitmap, mRectSrc, mRectDes, null);
                getHolder().unlockCanvasAndPost(c);
            }
        }
    }



    private void dragAction(MotionEvent event) {
        final int dragScale = 3;//放慢拖动速率
        synchronized (MySurfaceView3.class) {
            PointF currentPoint = new PointF();
            currentPoint.set(event.getX(), event.getY());
            int offsetX = (int) (currentPoint.x - mStartPoint.x) / dragScale;
            int offsetY = (int) (currentPoint.y - mStartPoint.y) / dragScale;
            mStartPoint = currentPoint;

            mCenterX -= offsetX;
            mCenterY -= offsetY;

            adjustCenter();
            showBitmap();
        }
    }

    private void zoomAcition(MotionEvent event) {
        synchronized (MySurfaceView3.class) {
            float newDist = spacing(event);
            float scale = newDist / mStartDistance;
            mStartDistance = newDist;

            mCurrentScale *= scale;
            mCurrentScale = Math.max(FLOAT_TYPE, Math.min(mCurrentScale, mCurrentMaxScale));

            calcRect();
            adjustCenter();
            showBitmap();
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (isDrawShape) {
            if (mRectDes.left > event.getX() || mRectDes.right < event.getX()) {
                return false;
            } else if (mRectDes.top > event.getY() || mRectDes.bottom < event.getY()) {
                return false;
            }

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    startX = pointScreen2ImageX(mImageWidth, event.getX());
                    startY = pointScreen2ImageY(mImageHeight, event.getY());
                    endX = startX;
                    endY = startY;

                    break;

                case MotionEvent.ACTION_MOVE:
                    endX = pointScreen2ImageX(mImageWidth, event.getX());
                    endY = pointScreen2ImageY(mImageHeight, event.getY());
                    break;

                case MotionEvent.ACTION_UP:
                    endX = pointScreen2ImageX(mImageWidth, event.getX());
                    endY = pointScreen2ImageY(mImageHeight, event.getY());

                    break;
            }

            showBitmap();
            return true;
        }

        //缩放部分
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mStartPoint.set(event.getX(), event.getY());
                mStatus = DRAG;
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                float distance = spacing(event);
                if (distance > 10f) {
                    mStatus = ZOOM;
                    mStartDistance = distance;
                }
                break;

            case MotionEvent.ACTION_MOVE:
                if (mStatus == DRAG) {
                    dragAction(event);
                } else {
                    if (event.getPointerCount() == 1)
                        return true;
                    zoomAcition(event);
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mStatus = NONE;
                break;
        }

        return true;
    }

    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
    }

    // 初始化
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        synchronized (MySurfaceView3.class) {
            mRectDes.set(0, 0, width, height);
            mSurfaceHeight = height;
            mSurfaceWidth = width;
            init();
            if (mBitmap != null) {
                showBitmap();
            }
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }
}
